#pragma once
#include "prs_Data.h"

namespace prs {
///////////////////////////////////////////////////////////////////////////////
struct TDataTree;
///////////////////////////////////////////////////////////////////////////////
/******
struct TDataTR
{
  svl::TString TableId;
  int RecordId;
  //
  TDataTR(const svl::TString &TableId_,int RecordId_) {
		TableId = TableId_;
		RecordId = RecordId;
  }
};
**********/
///////////////////////////////////////////////////////////////////////////////

struct TDataTreeRecord : public TDebug
{
	TDataTreeRecord(TDataTree	&DataTree);
	TDataTreeRecord(TDataTreeRecord	&DataTreeRecord);
	//
	void operator = (const TDataTreeRecord &From) {
		childRecord  = From.childRecord;
		treeRecord   = From.treeRecord;
		itemToTable  = From.itemToTable;
		itemToRecord = From.itemToRecord;
	}
	//
	TDataTable       *GetItemToTable()  const { return itemToTable;}
	TDataTableRecord *GetItemToRecord() const { return itemToRecord;}
	//
	void SetItemName(const svl::TString &Value);
	svl::TString GetItemName();
	//
	int GetChildrenCount();
	TDataTreeRecord GetChild(int NChild);
	
	// ToTableId,ToRecordId	/////////////////////////////////////////////////////////////////////
	TDataTreeRecord AddChildFirst(const TTableId &ItemToTableId,const TRecordId &ItemToRecordId);
	TDataTreeRecord AddChildLast (const TTableId &ItemToTableId,const TRecordId &ItemToRecordId);
	//
	TDataTreeRecord AddChildBefore(const TDataTreeRecord &Current,const TTableId &ItemToTableId,const TRecordId &ItemToRecordId);
	TDataTreeRecord AddChildAfter (const TDataTreeRecord &Current,const TTableId &ItemToTableId,const TRecordId &ItemToRecordId);

	// TDataTypedRecordBase	/////////////////////////////////////
	TDataTreeRecord AddChildFirst(const TDataTypedRecordBase &To) { return AddChildFirst(To.GetTableId(),To.GetRecordId());}
	TDataTreeRecord AddChildLast (const TDataTypedRecordBase &To) { return AddChildLast (To.GetTableId(),To.GetRecordId());}
	//
	TDataTreeRecord AddChildBefore(const TDataTreeRecord &Current,const TDataTypedRecordBase &To) { return AddChildBefore(Current,To.GetTableId(),To.GetRecordId());}
	TDataTreeRecord AddChildAfter (const TDataTreeRecord &Current,const TDataTypedRecordBase &To) { return AddChildAfter (Current,To.GetTableId(),To.GetRecordId());}

private:
	void NewTreeRecord(const TTableId &ItemToTableId,const TRecordId &ItemToRecordId);
	//
	TDataTree	&dataTree;
  TDataRefRRecord *childRecord;
	TDataTableRecord *treeRecord;
	TDataTable *itemToTable;
	TDataTableRecord *itemToRecord;

	friend TDataTree;
	svl_Except;
};

///////////////////////////////////////////////////////////////////////////////

struct TDataTree : public TDebug
{
	TDataTree(
	  TDataTables &Tables,
	  const TTableId &TableId
	);
  //
  TDataTable *GetTable() { return table;}
	//
	TDataTreeRecord AddRootRecord(const TTableId &ItemTableId,const TRecordId &ItemRecordId);
	TDataTreeRecord AddRootRecord(const TDataTypedRecordBase &Record);
	//
	TDataTreeRecord GetRecord(const TRecordId &TreeRecordId);

private:
  TDataTables &tables;
  TDataTable *table;
  svl::TString itemFieldId,childrenFieldId;
	friend TDataTreeRecord;
};

///////////////////////////////////////////////////////////////////////////////
}
